home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
thesrc10.zip
/
COMM3.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-11
|
24KB
|
732 lines
/***********************************************************************/
/* COMM3.C - Commands K-O */
/* This file contains all commands that can be assigned to function */
/* keys or typed on the command line. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991,1992 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@itc.gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 7877
* QLD 4121
* Australia
*/
#include <stdio.h>
#include <stdlib.h>
#include "the.h"
/*#define DEBUG 1*/
/*-------------------------- external data ----------------------------*/
extern LINE *next_line,*curr_line;
extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern char display_screens; /* number of screens */
extern char current_file; /* pointer to current file */
extern WINDOW *foot,*error_window;
extern char error_on_screen;
extern unsigned char *rec;
extern unsigned short rec_len;
extern unsigned char mode_insert; /* defines insert mode toggle */
extern unsigned char in_profile; /* indicates if processing profile */
extern unsigned char temp_cmd[150];
extern unsigned char *last_target;
/*---------------------- function definitions -------------------------*/
#ifdef PROTO
void split_command(unsigned char *,unsigned char *,unsigned char *);
int param_split(unsigned char *,unsigned char *[],int );
long valid_target(unsigned char *);
int get_row_for_focus_line(int,long,long);
#else
void split_command();
int param_split();
long valid_target();
int get_row_for_focus_line();
#endif
/*man-start*********************************************************************
COMMAND
left_arrow - move the cursor left one column
SYNTAX
** effective only if bound to a key **
DESCRIPTION
The left_arrow command moves the cursor left one column in the
current window. Scrolling of the main window horizontally, occurs
if the cursor is at the left-most column and the left-most column
is not the first column of the line.
COMPATIBILITY
Compatible.
SEE ALSO
Right_arrow
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Left_arrow(unsigned char *params)
#else
int Left_arrow(params)
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short x,y;
short col,old_col;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Left_arrow");
#endif
getyx(CURRENT_WINDOW,y,x);
/*---------------------------------------------------------------------*/
/* For all windows, if we are not at left column, move 1 pos to left. */
/*---------------------------------------------------------------------*/
if (x > 0)
{
wmove(CURRENT_WINDOW,y,x-1);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*---------------------------------------------------------------------*/
/* For MAIN windows if we are at left column, shift to left half the */
/* width of the main window or util column 0 is the left-most column. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_MAIN)
if (x == 0 && CURRENT_VIEW->verify_start != CURRENT_VIEW->verify_col)
{
old_col = (CURRENT_VIEW->verify_col-1);
x = CURRENT_SCREEN.cols / 2;
col = max((short)CURRENT_VIEW->verify_start,
(short)(CURRENT_VIEW->verify_col-1) - (short)x);
CURRENT_VIEW->verify_col = col;
show_page();
x = old_col - (CURRENT_VIEW->verify_col-1);
wmove(CURRENT_WINDOW,y,x-1);
}
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*man-start*********************************************************************
COMMAND
locate - find the next/prev occurrence of a string
SYNTAX
[Locate] [string target]
DESCRIPTION
The LOCATE command looks for the next or previous occurrence of the
specified string target. If no parameter is supplied, LOCATE
searches for the string that was used as the last string target, if
such a string exists.
COMPATIBILITY
Compatible.
Does not support not,and,or combinations of string targets.
ie ~,& and | not supported.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Locate(unsigned char *params)
#else
int Locate(params)
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short x,y;
short rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Locate");
#endif
/*---------------------------------------------------------------------*/
/* If no parameter is specified, use the last_target. If that doesn't */
/* exist, error. */
/*---------------------------------------------------------------------*/
if (strcmp(params,"") == 0)
{
if (strcmp(last_target,"") == 0)
{
display_error(39,"");
#ifdef TRACE
trace_return();
#endif
return(OK);
}
rc = command_line(last_target);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
rc = command_line(params);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
mark - mark a portion of text
SYNTAX
MARK Line|Box|Stream
DESCRIPTION
The MARK command marks a portion of text for later processing
usually by a COPY or MOVE command.
COMPATIBILITY
Does not implement Box or Stream...yet.
STATUS
Complete...LINE option is anyway.
**man-end**********************************************************************/
#ifdef PROTO
int Mark(unsigned char *params)
#else
int Mark(params)
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
long true_line;
unsigned short y,x;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Mark");
#endif
if (strcmp(params,"line") != 0)
{
display_error(1,params);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
true_line = CURRENT_VIEW->current_line;
else
true_line = CURRENT_VIEW->focus_line;
/*---------------------------------------------------------------------*/
/* If we are on 'Top of File' or 'Bottom of File' lines, error. */
/*---------------------------------------------------------------------*/
if (true_line == 0L || true_line == CURRENT_FILE->number_lines+1)
{
display_error(38,"");
#ifdef TRACE
trace_return();
#endif
return(OK);
}
MARK_VIEW = CURRENT_VIEW;
/*---------------------------------------------------------------------*/
/* Set the new values for top and bottom lines marked. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->mark_start_line == (-1L)
&& CURRENT_VIEW->mark_end_line == (-1L))
CURRENT_VIEW->mark_start_line = CURRENT_VIEW->mark_end_line = true_line;
else
{
if (true_line > CURRENT_VIEW->mark_end_line)
CURRENT_VIEW->mark_end_line = true_line;
if (true_line < CURRENT_VIEW->mark_start_line)
CURRENT_VIEW->mark_start_line = true_line;
if (true_line < CURRENT_VIEW->mark_end_line
&& true_line > CURRENT_VIEW->mark_start_line)
{
if (true_line-CURRENT_VIEW->mark_end_line >
CURRENT_VIEW->mark_start_line-true_line)
CURRENT_VIEW->mark_end_line = true_line;
else
CURRENT_VIEW->mark_start_line = true_line;
show_page();
}
}
/*---------------------------------------------------------------------*/
/* Now it is time to display the highlighted line(s). */
/*---------------------------------------------------------------------*/
getyx(CURRENT_WINDOW,y,x);
show_highlighted_lines();
/*---------------------------------------------------------------------*/
/* If the current line is inside the marked block, highlight it. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_line >= CURRENT_VIEW->mark_start_line
&& CURRENT_VIEW->current_line <= CURRENT_VIEW->mark_end_line)
highlight_line(CURRENT_VIEW->current_row,colour[ATTR_CBLOCK]);
wmove(CURRENT_WINDOW,y,x);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*man-start*********************************************************************
COMMAND
move - move a portion of text
SYNTAX
MOVE BLOCK
DESCRIPTION
The MARK command marks a portion of text for later processing
usually by a COPY or MOVE command.
COMPATIBILITY
Does not implement Box or Stream...yet.
STATUS
Bug with positioning of cursor when moving text from one view to
another. The cursor is left where it was when in that view. If the
delete of lines causes the bottom of the file to be positioned
above the focus line, the cursor will appear in no-man's land.
Use refresh to correct display.
**man-end**********************************************************************/
#ifdef PROTO
int Move(unsigned char *params)
#else
int Move(params)
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define MOVE_PARAMS 1
unsigned char *word[MOVE_PARAMS+1];
unsigned short num_params;
long num_lines;
LINE *curr,*old_curr,*save_old_curr;
register int i;
unsigned short y,x;
bool same_file;
unsigned long li;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Move");
#endif
num_params = param_split(params,word,MOVE_PARAMS);
if (strcmp(word[0],"block") != 0)
{
display_error(1,word[0]);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*---------------------------------------------------------------------*/
/* If on the command line, error. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
{
display_error(38,"");
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*---------------------------------------------------------------------*/
/* If no marked block in any view, return error. */
/*---------------------------------------------------------------------*/
if (MARK_VIEW == (VIEW_DETAILS *)NULL)
{
display_error(44,"");
#ifdef TRACE
trace_return();
#endif
return(OK);
}
post_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Determine the number of lines in the marked block (any view) */
/*---------------------------------------------------------------------*/
num_lines = MARK_VIEW->mark_end_line-MARK_VIEW->mark_start_line+1;
/*---------------------------------------------------------------------*/
/* Find the LINE pointer for start of marked block. */
/*---------------------------------------------------------------------*/
old_curr = ll_find(MARK_FILE->first_line,MARK_VIEW->mark_start_line);
save_old_curr = old_curr;
/*---------------------------------------------------------------------*/
/* Find the LINE pointer for the current focus line. */
/* If the focus line is the bottom of file line, subtract 1 from it. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->focus_line == CURRENT_FILE->number_lines+1)
li = 1L;
else
li = 0L;
curr = ll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line-li);
/*---------------------------------------------------------------------*/
/* Add each line from the marked view after the current focus line. */
/*---------------------------------------------------------------------*/
for (i=0;i<num_lines;i++)
{
if ((curr = add_line(CURRENT_FILE->first_line,curr,
old_curr->line,old_curr->length)) == NULL)
{
display_error(30,"");
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
old_curr = old_curr->next;
}
/*---------------------------------------------------------------------*/
/* Increment the number of lines counter for the current file and the */
/* number of alterations. */
/*---------------------------------------------------------------------*/
increment_alt();
CURRENT_FILE->number_lines += num_lines;
/*---------------------------------------------------------------------*/
/* Delete from the linked list the number of lines specified in the */
/* direction specified for the marked file. */
/*---------------------------------------------------------------------*/
for (i=0;i<num_lines;i++)
save_old_curr = ll_del(MARK_FILE->first_line,
save_old_curr,DIRECTION_FORWARD);
/*---------------------------------------------------------------------*/
/* Decrement the number of lines counter for the marked file and the */
/* number of alterations. Don't worry about testing for AUTOSAVE. */
/*---------------------------------------------------------------------*/
MARK_FILE->autosave_alt++;
MARK_FILE->save_alt++;
MARK_FILE->number_lines -= num_lines;
/*---------------------------------------------------------------------*/
/* Determine where the focus_line should end up. If the marked block is*/
/* in the same view and is above the focus_line, change it. */
/*---------------------------------------------------------------------*/
if (MARK_VIEW == CURRENT_VIEW)
{
same_file = TRUE;
if (MARK_VIEW->mark_start_line < CURRENT_VIEW->focus_line)
{
CURRENT_VIEW->focus_line -= num_lines;
i = 0;
}
else
i = 1;
}
else
{
same_file = FALSE;
i = 1;
}
/*---------------------------------------------------------------------*/
/* Set the highlighting of lines up. The newly copied block remains */
/* marked in the current view and the previous marked block is reset. */
/*---------------------------------------------------------------------*/
MARK_VIEW->mark_start_line = MARK_VIEW->mark_end_line = (-1L);
CURRENT_VIEW->mark_start_line = CURRENT_VIEW->focus_line + 1L;
CURRENT_VIEW->mark_end_line = CURRENT_VIEW->focus_line + num_lines;
CURRENT_VIEW->focus_line = CURRENT_VIEW->mark_start_line;
/*---------------------------------------------------------------------*/
/* The following does a 'reset block' in the current view. */
/*---------------------------------------------------------------------*/
CURRENT_VIEW->mark_start_line = CURRENT_VIEW->mark_end_line = (-1L);
MARK_VIEW = (VIEW_DETAILS *)NULL;
pre_process_line(CURRENT_VIEW->focus_line);
getyx(CURRENT_WINDOW,y,x);
if (y == CURRENT_SCREEN.rows-1 /* on bottom line of window */
&& !same_file) /* and different files */
{
CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
y = CURRENT_VIEW->current_row;
i = 0;
}
else
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
show_page();
wmove(CURRENT_WINDOW,y,x);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*man-start*********************************************************************
COMMAND
next - move forward in the file a number of lines
SYNTAX
Next [target]
DESCRIPTION
The NEXT command moves the current_line forwards the number of
lines specified by the target. Negative targets move backwards
through the file.
COMPATIBILITY
Compatible.
SEE ALSO
Up
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Next(unsigned char *params)
#else
int Next(params)
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define NEX_PARAMS 1
unsigned char *word[NEX_PARAMS+1];
unsigned short num_params;
long num_lines;
unsigned short y,x;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Next");
#endif
num_params = param_split(params,word,NEX_PARAMS);
if (num_params == 0)
{
num_params = 1;
word[0] = (unsigned char *)"1";
}
if (num_params != 1)
{
display_error(1,word[1]);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
if ((num_lines = valid_target(word[0])) == TARGET_ERROR)
{
display_error(4,word[0]);
#ifdef TRACE
trace_return();
#endif
return(ERROR);
}
post_process_line(CURRENT_VIEW->focus_line);
if (in_profile || CURRENT_VIEW->current_window == WINDOW_COMMAND)
{
CURRENT_VIEW->current_line += num_lines;
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line;
pre_process_line(CURRENT_VIEW->focus_line);
if (!in_profile)
show_page();
}
else
{
getyx(CURRENT_WINDOW,y,x);
CURRENT_VIEW->focus_line += num_lines;
pre_process_line(CURRENT_VIEW->focus_line);
if (num_lines + y <= 0
|| num_lines + y >= CURRENT_SCREEN.rows)
{
CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
y = CURRENT_VIEW->current_row;
}
else
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
show_page();
wmove(CURRENT_WINDOW,y,x);
}
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*man-start*********************************************************************
COMMAND
nextwindow - switch focus of editting session to other window
SYNTAX
NEXTWindow
DESCRIPTION
The NEXTWINDOW command moves the focus of the editting session to
the other window (if more than one window is currently displayed)
or to the next file in the ring.
COMPATIBILITY
Compatible.
SEE ALSO
Edit,Screen
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Nextwindow(unsigned char *params)
#else
int Nextwindow(params)
unsigned char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Nextwindow");
#endif
if (strcmp(params,"") != 0)
{
display_error(1,params);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
if (display_screens == 1)
{
rc = Edit("");
#ifdef TRACE
trace_return();
#endif
return(rc);
}
post_process_line(CURRENT_VIEW->focus_line);
current_screen = (current_screen == 0) ? 1 : 0;
CURRENT_VIEW = CURRENT_SCREEN.screen_view;
pre_process_line(CURRENT_VIEW->focus_line);
#ifdef TRACE
trace_return();
#endif
return(OK);
}
/*man-start*********************************************************************
COMMAND
os_cmd - execute an operating system command
SYNTAX
!|dos [command]
DESCRIPTION
The OS_CMD command executes the supplied os command.
This command is not called directly but is called with the ! or
dos commands.
COMPATIBILITY
Compatible.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Os_cmd(unsigned char *params)
#else
int Os_cmd(params)
unsigned char *params;
#endif
/***********************************************************************/
{
#if defined(DOS) || defined(OS2)
#define SHELL "COMSPEC"
#else
#define SHELL "SHELL"
#endif
/*--------------------------- local data ------------------------------*/
#define OS_PARAMS 1
unsigned char *word[OS_PARAMS+1];
char parm[OS_PARAMS];
register int i;
unsigned short num_params;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm3.c: Os_cmd");
#endif
touchwin(stdscr);
wmove(stdscr,0,0);
wrefresh(stdscr); /* clear screen */
/* really should get COMSPEC (DOS) or SHELL (UNIX) and run that */
#ifdef UNIX
reset_shell_mode();
#endif
if (strcmp(params,"") == 0)
strcpy(temp_cmd,getenv(SHELL));
else
strcpy(temp_cmd,params);
system(temp_cmd);
printf("\n\nHit any key to continue...");
fflush(stdout);
#ifdef UNIX
reset_prog_mode();
#endif
wgetch(stdscr);
wrefresh(curscr); /* clear screen */
touchwin(foot);
wnoutrefresh(foot);
touchwin(CURRENT_WINDOW_IDLINE);
wnoutrefresh(CURRENT_WINDOW_IDLINE);
touchwin(CURRENT_WINDOW_MAIN);
wnoutrefresh(CURRENT_WINDOW_MAIN);
touchwin(CURRENT_WINDOW_ARROW);
wnoutrefresh(CURRENT_WINDOW_ARROW);
if (CURRENT_VIEW->prefix_on)
{
touchwin(CURRENT_WINDOW_PREFIX);
wnoutrefresh(CURRENT_WINDOW_PREFIX);
}
touchwin(CURRENT_WINDOW_COMMAND);
wnoutrefresh(CURRENT_WINDOW_COMMAND);
doupdate();
#if defined(DOS) || defined(OS2)
draw_cursor();
#endif
#ifdef TRACE
trace_return();
#endif
return(OK);
}